package edu.haw.cg.datastructures;

/**
 * 
 * Praktikum CG WP WS13/14
 * Gruppe: Andreas Rebri(andreas.rebri@haw-hamburg.de)
 * 		   Joschka Schulz(joschka.schulz@haw-hamburg.de)
 * Aufgabe : Aufgabenblatt 4
 * Verwendete Quellen: -
 */

import java.util.ArrayList;
import java.util.List;

/**
 * Implementation of the Interface IHalfEdgeDatastructureOperations containing
 * operations based on the half edge data structure.
 */
public class HalfEdgeDatastructureOperations implements
		IHalfEdgeDatastructureOperations {

	/**
	 * Return a list of adjacent vertices for a given vertex.
	 * 
	 * @param vertex
	 *            Initial vertex.
	 * @return List of adjacent vertices.
	 */
	@Override
	public List<HalfEdgeVertex> getAdjacentVertices(HalfEdgeVertex vertex) {
		List<HalfEdgeVertex> vertexList = new ArrayList<HalfEdgeVertex>();
		HalfEdge halfEdge = vertex.getHalfEdge().getPrev();
		vertexList.add(halfEdge.getVertex());
		boolean end = false;
		while (!end) {
			halfEdge = halfEdge.getOpposite().getPrev();
			if (vertexList.contains(halfEdge.getVertex())) {
				end = true;
			} else {
				vertexList.add(halfEdge.getVertex());
			}
		}

		return vertexList;
	}

	/**
	 * Return a list of incident facets of a vertex.
	 * 
	 * @param vertex
	 *            Central query vertex.
	 * @return List of incident facets.
	 */
	@Override
	public List<IHalfEdgeFacet> getIncidentFacets(HalfEdgeVertex vertex) {
		List<IHalfEdgeFacet> faceList = new ArrayList<IHalfEdgeFacet>();
		HalfEdge halfEdge = vertex.getHalfEdge();

		HalfEdgeVertex currentVertex = vertex;
		boolean end = false;
		while (!end) {
			if (faceList.contains(halfEdge.getFacet())) {
				end = true;
			} else {
				faceList.add(halfEdge.getFacet());
				halfEdge = halfEdge.getPrev().getOpposite();
			}
		}

		return faceList;
	}

	/**
	 * Return a list if adjacent half edges (incoming and outgoing) for a given
	 * vertex.
	 * 
	 * @param vertex
	 *            Central query vertex.
	 * @return List of incident half edges.
	 */
	@Override
	public List<HalfEdge> getIncidetEdges(HalfEdgeVertex vertex) {
		List<HalfEdge> edgeList = new ArrayList<HalfEdge>();
		HalfEdge currentEdge = vertex.getHalfEdge();

		edgeList.add(currentEdge);
		edgeList.add(currentEdge.getOpposite());

		boolean end = false;
		while (!end) {
			currentEdge = currentEdge.getOpposite().getNext();
			if (edgeList.contains(currentEdge)) {
				end = true;
			} else {
				edgeList.add(currentEdge);
				edgeList.add(currentEdge.getOpposite());
			}
		}

		return edgeList;
	}

	/**
	 * Return a list of incident vertices to a given facet.
	 * 
	 * @param facet
	 *            Query facet.
	 * @return List of incident vertices.
	 */
	@Override
	public List<HalfEdgeVertex> getIncidentVertices(IHalfEdgeFacet facet) {
		List<HalfEdgeVertex> vertices = new ArrayList<>();
		HalfEdge currentEdge = facet.getHalfEdge();

		boolean end = false;
		while (!end) {
			if (vertices.contains(currentEdge.getVertex())) {
				end = true;
			} else {
				vertices.add(currentEdge.getVertex());
				currentEdge = currentEdge.getNext();
			}
		}

		return vertices;
	}

	/**
	 * Return the list of incident facets of a given facet.
	 * 
	 * @param facet
	 *            Query facet.
	 * @return List of incident facets.
	 */
	@Override
	public List<IHalfEdgeFacet> getIncidentFacets(IHalfEdgeFacet facet) {
		List<IHalfEdgeFacet> faces = new ArrayList<>();
		HalfEdge currentEdge = facet.getHalfEdge();

		boolean end = false;
		while (!end) {
			if (faces.contains(currentEdge.getOpposite().getFacet())) {
				end = true;
			} else {
				faces.add(currentEdge.getOpposite().getFacet());
				currentEdge = currentEdge.getNext();
			}
		}

		return faces;
	}

	/**
	 * Return a list of incident half edges for a given facet. Only the half
	 * edges corresponding to the facet are returned, opposite edges are
	 * ignored.
	 * 
	 * @param facet
	 *            Query facet.
	 * @return List of incident facets.
	 */
	@Override
	public List<HalfEdge> getIncidentHalfEdges(IHalfEdgeFacet facet) {
		List<HalfEdge> edges = new ArrayList<>();
		HalfEdge currentEdge = facet.getHalfEdge();

		boolean end = false;
		while (!end) {
			if (edges.contains(currentEdge)) {
				end = true;
			} else {
				edges.add(currentEdge);
				currentEdge = currentEdge.getNext();
			}
		}

		return edges;
	}
}
